1
|
|
|
/*! |
2
|
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined |
3
|
|
|
* in FIPS 180-1 |
4
|
|
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined |
5
|
|
|
* in FIPS 180-2 |
6
|
|
|
* |
7
|
|
|
* Version 2.2 Copyright Paul Johnston 2000 - 2009. |
8
|
|
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet |
9
|
|
|
* |
10
|
|
|
* Distributed under the BSD License |
11
|
|
|
* See http://pajhome.org.uk/crypt/md5 for details. |
12
|
|
|
* Also http://anmar.eu.org/projects/jssha2/ |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Configurable variables. You may need to tweak these to be compatible with |
17
|
|
|
* the server-side, but the defaults work in most cases. |
18
|
|
|
*/ |
19
|
|
|
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ |
20
|
|
|
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* These are the functions you'll want to call |
24
|
|
|
* They take string arguments and return hex encoded strings |
25
|
|
|
*/ |
26
|
|
|
function hex_sha1(s) {return rstr2hex(rstr_sha1(str2rstr_utf8(s)));} |
27
|
|
|
function hex_sha256(s) {return rstr2hex(rstr_sha256(str2rstr_utf8(s)));} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Calculate the SHA1 of a raw string |
31
|
|
|
*/ |
32
|
|
|
function rstr_sha1(s) |
33
|
|
|
{ |
34
|
|
|
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8)); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Calculate the sha256 of a raw string |
39
|
|
|
*/ |
40
|
|
|
function rstr_sha256(s) |
41
|
|
|
{ |
42
|
|
|
return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8)); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Encode a string as utf-8. |
47
|
|
|
* For efficiency, this assumes the input is valid utf-16. |
48
|
|
|
*/ |
49
|
|
|
function str2rstr_utf8(input) |
50
|
|
|
{ |
51
|
|
|
var output = ""; |
52
|
|
|
var i = -1; |
53
|
|
|
var x, y; |
54
|
|
|
|
55
|
|
|
while (++i < input.length) |
56
|
|
|
{ |
57
|
|
|
/* Decode utf-16 surrogate pairs */ |
58
|
|
|
x = input.charCodeAt(i); |
59
|
|
|
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; |
60
|
|
|
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) |
61
|
|
|
{ |
62
|
|
|
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); |
63
|
|
|
i++; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/* Encode output as utf-8 */ |
67
|
|
|
if (x <= 0x7F) |
68
|
|
|
output += String.fromCharCode(x); |
|
|
|
|
69
|
|
|
else if (x <= 0x7FF) |
70
|
|
|
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), |
|
|
|
|
71
|
|
|
0x80 | (x & 0x3F)); |
72
|
|
|
else if (x <= 0xFFFF) |
73
|
|
|
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), |
|
|
|
|
74
|
|
|
0x80 | ((x >>> 6) & 0x3F), |
75
|
|
|
0x80 | (x & 0x3F)); |
76
|
|
|
else if (x <= 0x1FFFFF) |
77
|
|
|
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), |
|
|
|
|
78
|
|
|
0x80 | ((x >>> 12) & 0x3F), |
79
|
|
|
0x80 | ((x >>> 6) & 0x3F), |
80
|
|
|
0x80 | (x & 0x3F)); |
81
|
|
|
} |
82
|
|
|
return output; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Convert a raw string to an array of big-endian words |
87
|
|
|
* Characters >255 have their high-byte silently ignored. |
88
|
|
|
*/ |
89
|
|
|
function rstr2binb(input) |
90
|
|
|
{ |
91
|
|
|
var output = Array(input.length >> 2); |
92
|
|
|
for (var i = 0; i < output.length; i++) |
93
|
|
|
output[i] = 0; |
|
|
|
|
94
|
|
|
for (var i = 0; i < input.length * 8; i += 8) |
|
|
|
|
95
|
|
|
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); |
|
|
|
|
96
|
|
|
return output; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Convert an array of big-endian words to a string |
101
|
|
|
*/ |
102
|
|
|
function binb2rstr(input) |
103
|
|
|
{ |
104
|
|
|
var output = ""; |
105
|
|
|
for (var i = 0; i < input.length * 32; i += 8) |
106
|
|
|
output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF); |
|
|
|
|
107
|
|
|
return output; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Calculate the SHA-1 of an array of big-endian words, and a bit length |
112
|
|
|
*/ |
113
|
|
|
function binb_sha1(x, len) |
114
|
|
|
{ |
115
|
|
|
/* append padding */ |
116
|
|
|
x[len >> 5] |= 0x80 << (24 - len % 32); |
117
|
|
|
x[((len + 64 >> 9) << 4) + 15] = len; |
118
|
|
|
|
119
|
|
|
var w = Array(80); |
120
|
|
|
var a = 1732584193; |
121
|
|
|
var b = -271733879; |
122
|
|
|
var c = -1732584194; |
123
|
|
|
var d = 271733878; |
124
|
|
|
var e = -1009589776; |
125
|
|
|
|
126
|
|
|
for (var i = 0; i < x.length; i += 16) |
127
|
|
|
{ |
128
|
|
|
var olda = a; |
129
|
|
|
var oldb = b; |
130
|
|
|
var oldc = c; |
131
|
|
|
var oldd = d; |
132
|
|
|
var olde = e; |
133
|
|
|
|
134
|
|
|
for (var j = 0; j < 80; j++) |
135
|
|
|
{ |
136
|
|
|
if (j < 16) |
137
|
|
|
w[j] = x[i + j]; |
|
|
|
|
138
|
|
|
else |
139
|
|
|
w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); |
140
|
|
|
var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), |
141
|
|
|
safe_add(safe_add(e, w[j]), sha1_kt(j))); |
142
|
|
|
e = d; |
143
|
|
|
d = c; |
144
|
|
|
c = bit_rol(b, 30); |
145
|
|
|
b = a; |
146
|
|
|
a = t; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
a = safe_add(a, olda); |
150
|
|
|
b = safe_add(b, oldb); |
151
|
|
|
c = safe_add(c, oldc); |
152
|
|
|
d = safe_add(d, oldd); |
153
|
|
|
e = safe_add(e, olde); |
154
|
|
|
} |
155
|
|
|
return Array(a, b, c, d, e); |
156
|
|
|
|
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Perform the appropriate triplet combination function for the current |
161
|
|
|
* iteration |
162
|
|
|
*/ |
163
|
|
|
function sha1_ft(t, b, c, d) |
164
|
|
|
{ |
165
|
|
|
if (t < 20) |
166
|
|
|
return (b & c) | ((~b) & d); |
|
|
|
|
167
|
|
|
if (t < 40) |
168
|
|
|
return b ^ c ^ d; |
|
|
|
|
169
|
|
|
if (t < 60) |
170
|
|
|
return (b & c) | (b & d) | (c & d); |
|
|
|
|
171
|
|
|
return b ^ c ^ d; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Determine the appropriate additive constant for the current iteration |
176
|
|
|
*/ |
177
|
|
|
function sha1_kt(t) |
178
|
|
|
{ |
179
|
|
|
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : |
180
|
|
|
(t < 60) ? -1894007588 : -899497514; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Bitwise rotate a 32-bit number to the left. |
185
|
|
|
*/ |
186
|
|
|
function bit_rol(num, cnt) |
187
|
|
|
{ |
188
|
|
|
return (num << cnt) | (num >>> (32 - cnt)); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Convert a raw string to a hex string |
193
|
|
|
*/ |
194
|
|
|
function rstr2hex(input) |
195
|
|
|
{ |
196
|
|
|
try { |
197
|
|
|
hexcase |
198
|
|
|
} catch (e) { |
|
|
|
|
199
|
|
|
hexcase = 0; |
|
|
|
|
200
|
|
|
} |
201
|
|
|
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; |
202
|
|
|
var output = ""; |
203
|
|
|
var x; |
204
|
|
|
for (var i = 0; i < input.length; i++) |
205
|
|
|
{ |
206
|
|
|
x = input.charCodeAt(i); |
207
|
|
|
output += hex_tab.charAt((x >>> 4) & 0x0F) |
208
|
|
|
+ hex_tab.charAt(x & 0x0F); |
209
|
|
|
} |
210
|
|
|
return output; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* Main sha256 function, with its support functions |
215
|
|
|
*/ |
216
|
|
|
function sha256_S(X, n) {return (X >>> n) | (X << (32 - n));} |
217
|
|
|
function sha256_R(X, n) {return (X >>> n);} |
218
|
|
|
function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} |
219
|
|
|
function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} |
220
|
|
|
function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));} |
221
|
|
|
function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));} |
222
|
|
|
function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));} |
223
|
|
|
function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));} |
224
|
|
|
function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));} |
225
|
|
|
function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));} |
226
|
|
|
function sha256_Gamma0512(x) {return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));} |
227
|
|
|
function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));} |
228
|
|
|
|
229
|
|
|
var sha256_K = new Array |
|
|
|
|
230
|
|
|
( |
231
|
|
|
1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, |
232
|
|
|
-1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, |
233
|
|
|
1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, |
234
|
|
|
264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, |
235
|
|
|
-1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, |
236
|
|
|
113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, |
237
|
|
|
1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, |
238
|
|
|
-1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, |
239
|
|
|
430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, |
240
|
|
|
1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, |
241
|
|
|
-1866530822, -1538233109, -1090935817, -965641998 |
242
|
|
|
); |
243
|
|
|
|
244
|
|
|
function binb_sha256(m, l) |
245
|
|
|
{ |
246
|
|
|
var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, 1359893119, -1694144372, 528734635, 1541459225); |
|
|
|
|
247
|
|
|
var W = new Array(64); |
248
|
|
|
var a, b, c, d, e, f, g, h; |
249
|
|
|
var i, j, T1, T2; |
250
|
|
|
|
251
|
|
|
/* append padding */ |
252
|
|
|
m[l >> 5] |= 0x80 << (24 - l % 32); |
253
|
|
|
m[((l + 64 >> 9) << 4) + 15] = l; |
254
|
|
|
|
255
|
|
|
for (i = 0; i < m.length; i += 16) |
256
|
|
|
{ |
257
|
|
|
a = HASH[0]; |
258
|
|
|
b = HASH[1]; |
259
|
|
|
c = HASH[2]; |
260
|
|
|
d = HASH[3]; |
261
|
|
|
e = HASH[4]; |
262
|
|
|
f = HASH[5]; |
263
|
|
|
g = HASH[6]; |
264
|
|
|
h = HASH[7]; |
265
|
|
|
|
266
|
|
|
for (j = 0; j < 64; j++) |
267
|
|
|
{ |
268
|
|
|
if (j < 16) |
269
|
|
|
W[j] = m[j + i]; |
|
|
|
|
270
|
|
|
else |
271
|
|
|
W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), |
272
|
|
|
sha256_Gamma0256(W[j - 15])), W[j - 16]); |
273
|
|
|
|
274
|
|
|
T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), |
275
|
|
|
sha256_K[j]), W[j]); |
276
|
|
|
T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); |
277
|
|
|
h = g; |
278
|
|
|
g = f; |
279
|
|
|
f = e; |
280
|
|
|
e = safe_add(d, T1); |
281
|
|
|
d = c; |
282
|
|
|
c = b; |
283
|
|
|
b = a; |
284
|
|
|
a = safe_add(T1, T2); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
HASH[0] = safe_add(a, HASH[0]); |
288
|
|
|
HASH[1] = safe_add(b, HASH[1]); |
289
|
|
|
HASH[2] = safe_add(c, HASH[2]); |
290
|
|
|
HASH[3] = safe_add(d, HASH[3]); |
291
|
|
|
HASH[4] = safe_add(e, HASH[4]); |
292
|
|
|
HASH[5] = safe_add(f, HASH[5]); |
293
|
|
|
HASH[6] = safe_add(g, HASH[6]); |
294
|
|
|
HASH[7] = safe_add(h, HASH[7]); |
295
|
|
|
} |
296
|
|
|
return HASH; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* Add integers, wrapping at 2^32. This uses 16-bit operations internally |
301
|
|
|
* to work around bugs in some JS interpreters. |
302
|
|
|
*/ |
303
|
|
|
function safe_add(x, y) |
304
|
|
|
{ |
305
|
|
|
var lsw = (x & 0xFFFF) + (y & 0xFFFF); |
306
|
|
|
var msw = (x >> 16) + (y >> 16) + (lsw >> 16); |
307
|
|
|
return (msw << 16) | (lsw & 0xFFFF); |
308
|
|
|
} |
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.